package com.shanks.home.net;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.http.Header;
import org.json.JSONObject;

import android.text.TextUtils;
import android.util.Log;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.SyncHttpClient;
import com.loopj.android.http.TextHttpResponseHandler;
import com.shanks.home.util.LogUtil;

/**
 * Http请求封装类，支持同步与异步调用，参数在内部使用ThreadLocal存储，因此从begin到request需要在同一线程中完成
 * @author Shanks
 * @time 2013.12.26
 */
public class HttpService {
	
	private static final String TAG = HttpService.class.getSimpleName();
	
	private static AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
	private static SyncHttpClient syncHttpClient = new SyncHttpClient();
	
	private static ThreadLocal<RequestParams> requestParams = new ThreadLocal<RequestParams>();
	private static ThreadLocal<HttpResponser> responder = new ThreadLocal<HttpResponser>();
	private static ThreadLocal<String> requestURL = new ThreadLocal<String>();
	private static ThreadLocal<String> method = new ThreadLocal<String>();
	
	private static ConcurrentMap<String, Object> defaultParaMap = new ConcurrentHashMap<String, Object>();
	private static String defaultUrl;
	
	/**
	 * 设置默认url
	 * @param url
	 */
	public static void setDefaultURL(String url) {
		defaultUrl = url;
	}
	
	/**
	 * 设置提交的目标url
	 * @param url
	 */
	public static void setURL(String url) {
		requestURL.set(url);
	}
	
	/**
	 * 添加一个默认参数，如果不需要默认参数，需要调用clearDefaultParams来取消默认参数
	 * @param name
	 * @param value
	 */
	public static void setDefaultParam(String name, Object value) {
		defaultParaMap.put(name, value);
	}

	/**
	 * 清除所有默认参数
	 */
	public static void clearDefaultParams() {
		defaultParaMap.clear();
	}
	
	/**
	 * 添加一个参数
	 * @param name
	 * @param value
	 */
	public static void addParameter(String name, Object value) {
		RequestParams param = requestParams.get();
		addParameter(param, name, value);
	}
	
	/**
	 * 添加一个输入流
	 * @param name
	 * @param is
	 * @param filename
	 */
	public static void addInputStream(String name, InputStream is, String filename) {
		RequestParams param = requestParams.get();
		param.put(name, is, filename);
	}
	
	/**
	 * 添加一个输入流
	 * @param name
	 * @param is
	 * @param filename
	 * @param contentType
	 */
	public static void addInputStream(String name, InputStream is, String filename, String contentType) {
		RequestParams param = requestParams.get();
		param.put(name, is, filename, contentType);
	}
	
	/**
	 * 添加一个文件
	 * @param name
	 * @param file
	 * @param contentType
	 */
	public static void addFile(String name, File file, String contentType) {
		RequestParams param = requestParams.get();
		try {
			param.put(name, file, contentType);
		} catch (FileNotFoundException e) {
		}
	}
	
	/**
	 * 本次调用清除掉所有默认参数
	 */
	public static void doNotUseDefaultParam() {
		RequestParams params = requestParams.get();
		if(params != null) {
			Iterator<String> it = defaultParaMap.keySet().iterator();
			while(it.hasNext()) {
				String key = it.next();
				params.remove(key);
			}
		}
	}
	
	/**
	 * 设置结果回调
	 * @param res
	 */
	public static void setResponder(HttpResponser res) {
		responder.set(res);
	}

	private static void clear() {
		requestParams.remove();
		responder.remove();
		requestURL.remove();
		method.remove();
	}
	
	private static RequestParams getDefaultRequestParams() {
		RequestParams params = new RequestParams();
		Iterator<String> it = defaultParaMap.keySet().iterator();
		while(it.hasNext()) {
			String key = it.next();
			addParameter(params, key, defaultParaMap.get(key));
		}
		return params;
	}
	
	@SuppressWarnings("unchecked")
	private static void addParameter(RequestParams params, String name, Object data) {
		try {
			if(params != null && data != null && name != null) {
				if(data instanceof List<?>) {
					params.put(name, (List<String>)data);
				} else if(data instanceof InputStream) {
					params.put(name, (InputStream)data);
				} else if(data instanceof File) {
					params.put(name, (File)data);
				} else {
					params.put(name, String.valueOf(data));
				}
			}
		} catch(Exception e) {
		}
	}
	
	/**
	 * 开始一个请求，使用Get方式提交，使用默认目标url
	 */
	public static void beginGET() {
		clear();
		
		requestParams.set(getDefaultRequestParams());
		requestURL.set(defaultUrl);
		method.set("GET");
	}
	
	/**
	 * 开始一个请求，使用Get方式提交，并指定目标url
	 * @param url
	 */
	public static void beginGET(String url) {
		clear();
		
		requestParams.set(getDefaultRequestParams());
		requestURL.set(defaultUrl);
		method.set("GET");
		
		if(!TextUtils.isEmpty(url)) {
			requestURL.set(url);
		} else {
		}
	}
	
	/**
	 * 开始一个请求，使用POST方式提交，使用默认目标url
	 */
	public static void beginPOST() {
		clear();
		
		HashMap<String, String> hashMap = new HashMap<String, String>();
		hashMap.put("mtkey", "ab8020a430b1fabbe695fe38cb14e469");
		hashMap.put("skey", "262f7ba27e521a32f3d4a57bcaad3446");
		hashMap.put("uid", "100257765");
		hashMap.put("device", "android");
		hashMap.put("deviceId", "867746017970302");
		hashMap.put("version", "1.0");
		
		JSONObject json = new JSONObject(hashMap);
		
		Log.v("", "JSONObject:" + json);
		
		try
		{
			HttpService.setDefaultParam("mtkey", json.getString("mtkey"));
			HttpService.setDefaultParam("skey", json.getString("skey"));
			HttpService.setDefaultParam("uid", json.getString("uid"));
			HttpService.setDefaultParam("device", "android");
			//DEVICE_ID
			HttpService.setDefaultParam("deviceId", json.getInt("deviceId"));
			//版本号
	        HttpService.setDefaultParam("version", json.getInt("version"));
		} catch (Exception e) {
			
		}
		
		requestParams.set(getDefaultRequestParams());
		requestURL.set("http://renren.coalaatexas.com/m.php");
		method.set("POST");
	}
	
	/**
	 * 开始一个请求，使用POST方式提交，并指定目标url
	 * @param url
	 */
	public static void beginPOST(String url) {
		clear();
		
		requestParams.set(getDefaultRequestParams());
		requestURL.set(defaultUrl);
		method.set("POST");
		
		if(!TextUtils.isEmpty(url)) {
			requestURL.set(url);
		} else {
		}
	}
	
	/**
	 * 发起同步请求
	 */
	public static void syncRequest() {
		String url = requestURL.get();
		RequestParams params = requestParams.get();
		HttpResponser resp = responder.get();
		String m = method.get();
		clear();
		
		syncRequest(m, url, params, resp);
	}
	
	/**
	 * 发起异步请求
	 */
	public static void asyncRequest() {
		String url = requestURL.get();
		RequestParams params = requestParams.get();
		HttpResponser resp = responder.get();
		String m = method.get();
		clear();
		
		asyncRequest(m, url, params, resp);
	}
	
	private static void syncRequest(final String method, final String url, final RequestParams params, final HttpResponser responder) {
		final AsyncHttpResponseHandler handler = new TextHttpResponseHandler() {
			
			@Override
			public void onSuccess(int status, Header[] headers, String responseString) {
				LogUtil.i(TAG, "succeed,status:" + status + " ----- data:" + responseString);
				try {
					if(responder != null) {
						responder.onSuccess(status, responseString);
					}
				} catch(Exception e) {
				}
			}
			
			@Override
			public void onFailure(int status, Header[] headers, String responseString, Throwable t) {
				LogUtil.i(TAG, "fail,status:" + status + " ----- data:" + responseString);
				try {
					if(responder != null) {
						responder.onFailure(t, responseString);
					}
				} catch(Exception e) {
				}
			}
		};
		if("POST".equals(method)) {
			syncHttpClient.post(url, params, handler);
		} else if("GET".equals(method)) {
			syncHttpClient.get(url, params, handler);
		}
	}
	
	private static void asyncRequest(final String method, final String url, final RequestParams params, final HttpResponser responder) {
		final AsyncHttpResponseHandler handler = new TextHttpResponseHandler() {
			@Override
			public void onSuccess(int status, Header[] headers, String responseString) {
				LogUtil.i(TAG, "succeed,status:" + status + " ----- data:" + responseString);
				try {
					if(responder != null) {
						responder.onSuccess(status, responseString);
					}
				} catch(Exception e) {
				}
			}
			@Override
			public void onFailure(int status, Header[] headers, String responseString, Throwable t) {
				LogUtil.i(TAG, "fail,status:" + status + " ----- data:" + responseString);
				try {
					if(responder != null) {
						responder.onFailure(t, responseString);
					}
				} catch(Exception e) {
				}
			}
		};
		if("POST".equals(method)) {
			Log.v("", "async post to " + url + " with param:" + params);
			asyncHttpClient.post(url, params, handler);
		} else if("GET".equals(method)) {
			Log.v("", "async get to " + url + " with param:" + params);
			asyncHttpClient.get(url, params, handler);
		}
	}
	
}
